use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use sysinfo::System;

/// 性能指标类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
    pub timestamp: u64,
    pub cpu_usage: f32,
    pub memory_usage: u64,
    pub memory_total: u64,
    pub disk_usage: u64,
    pub network_rx: u64,
    pub network_tx: u64,
    pub process_count: usize,
    pub uptime: u64,
    pub custom_metrics: HashMap<String, f64>,
}

/// 性能事件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceEvent {
    pub id: String,
    pub name: String,
    pub start_time: u64,
    pub end_time: Option<u64>,
    pub duration: Option<u64>,
    pub metadata: HashMap<String, serde_json::Value>,
}

/// 性能监控器
pub struct PerformanceMonitor {
    system: Arc<Mutex<System>>,
    metrics_history: Arc<Mutex<Vec<PerformanceMetrics>>>,
    active_events: Arc<Mutex<HashMap<String, PerformanceEvent>>>,
    completed_events: Arc<Mutex<Vec<PerformanceEvent>>>,
    start_time: Instant,
    custom_metrics: Arc<Mutex<HashMap<String, f64>>>,
}

impl PerformanceMonitor {
    /// 创建新的性能监控器
    pub fn new() -> Self {
        let mut system = System::new_all();
        system.refresh_all();

        Self {
            system: Arc::new(Mutex::new(system)),
            metrics_history: Arc::new(Mutex::new(Vec::new())),
            active_events: Arc::new(Mutex::new(HashMap::new())),
            completed_events: Arc::new(Mutex::new(Vec::new())),
            start_time: Instant::now(),
            custom_metrics: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    /// 收集当前性能指标
    pub fn collect_metrics(&self) -> PerformanceMetrics {
        let mut system = self.system.lock().unwrap();
        system.refresh_all();

        let timestamp = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();

        let cpu_usage = system.global_cpu_info().cpu_usage();
        let memory_usage = system.used_memory();
        let memory_total = system.total_memory();
        
        // 获取当前进程信息
        let _current_pid = std::process::id();
        let process_count = system.processes().len();
        
        // 计算运行时间
        let uptime = self.start_time.elapsed().as_secs();

        // 获取自定义指标
        let custom_metrics = self.custom_metrics.lock().unwrap().clone();

        let metrics = PerformanceMetrics {
            timestamp,
            cpu_usage,
            memory_usage,
            memory_total,
            disk_usage: 0, // 需要额外实现磁盘使用监控
            network_rx: 0, // 需要额外实现网络监控
            network_tx: 0,
            process_count,
            uptime,
            custom_metrics,
        };

        // 存储到历史记录
        let mut history = self.metrics_history.lock().unwrap();
        history.push(metrics.clone());
        
        // 限制历史记录数量（保留最近1000条）
        if history.len() > 1000 {
            history.remove(0);
        }

        metrics
    }

    /// 开始性能事件追踪
    pub fn start_event(&self, name: &str, metadata: HashMap<String, serde_json::Value>) -> String {
        let id = uuid::Uuid::new_v4().to_string();
        let event = PerformanceEvent {
            id: id.clone(),
            name: name.to_string(),
            start_time: SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_millis() as u64,
            end_time: None,
            duration: None,
            metadata,
        };

        self.active_events.lock().unwrap().insert(id.clone(), event);
        id
    }

    /// 结束性能事件追踪
    pub fn end_event(&self, event_id: &str) -> Option<PerformanceEvent> {
        let mut active_events = self.active_events.lock().unwrap();
        
        if let Some(mut event) = active_events.remove(event_id) {
            let end_time = SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_millis() as u64;
            
            event.end_time = Some(end_time);
            event.duration = Some(end_time - event.start_time);

            // 移动到完成事件列表
            let mut completed_events = self.completed_events.lock().unwrap();
            completed_events.push(event.clone());
            
            // 限制完成事件数量
            if completed_events.len() > 500 {
                completed_events.remove(0);
            }

            Some(event)
        } else {
            None
        }
    }

    /// 测量函数执行时间
    pub fn measure<F, R>(&self, name: &str, f: F) -> R 
    where 
        F: FnOnce() -> R,
    {
        let event_id = self.start_event(name, HashMap::new());
        let result = f();
        self.end_event(&event_id);
        result
    }

    /// 测量异步函数执行时间
    pub async fn measure_async<F, Fut, R>(&self, name: &str, f: F) -> R
    where
        F: FnOnce() -> Fut,
        Fut: std::future::Future<Output = R>,
    {
        let event_id = self.start_event(name, HashMap::new());
        let result = f().await;
        self.end_event(&event_id);
        result
    }

    /// 设置自定义指标
    pub fn set_custom_metric(&self, name: &str, value: f64) {
        self.custom_metrics.lock().unwrap().insert(name.to_string(), value);
    }

    /// 增加自定义指标
    pub fn increment_custom_metric(&self, name: &str, value: f64) {
        let mut metrics = self.custom_metrics.lock().unwrap();
        let current = *metrics.get(name).unwrap_or(&0.0);
        metrics.insert(name.to_string(), current + value);
    }

    /// 获取性能历史
    pub fn get_metrics_history(&self, limit: Option<usize>) -> Vec<PerformanceMetrics> {
        let history = self.metrics_history.lock().unwrap();
        if let Some(limit) = limit {
            history.iter().rev().take(limit).cloned().collect()
        } else {
            history.clone()
        }
    }

    /// 获取完成的事件
    pub fn get_completed_events(&self, limit: Option<usize>) -> Vec<PerformanceEvent> {
        let events = self.completed_events.lock().unwrap();
        if let Some(limit) = limit {
            events.iter().rev().take(limit).cloned().collect()
        } else {
            events.clone()
        }
    }

    /// 获取活跃事件
    pub fn get_active_events(&self) -> Vec<PerformanceEvent> {
        self.active_events.lock().unwrap().values().cloned().collect()
    }

    /// 生成性能报告
    pub fn generate_report(&self) -> PerformanceReport {
        let metrics_history = self.get_metrics_history(Some(100));
        let completed_events = self.get_completed_events(Some(50));
        let active_events = self.get_active_events();

        // 计算平均值
        let avg_cpu = if !metrics_history.is_empty() {
            metrics_history.iter().map(|m| m.cpu_usage).sum::<f32>() / metrics_history.len() as f32
        } else {
            0.0
        };

        let avg_memory = if !metrics_history.is_empty() {
            metrics_history.iter().map(|m| m.memory_usage).sum::<u64>() / metrics_history.len() as u64
        } else {
            0
        };

        // 计算事件统计
        let event_stats = self.calculate_event_stats(&completed_events);

        PerformanceReport {
            timestamp: SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_secs(),
            uptime: self.start_time.elapsed().as_secs(),
            avg_cpu_usage: avg_cpu,
            avg_memory_usage: avg_memory,
            total_events: completed_events.len(),
            active_events_count: active_events.len(),
            event_stats,
            recent_metrics: metrics_history,
            recent_events: completed_events,
        }
    }

    /// 计算事件统计
    fn calculate_event_stats(&self, events: &[PerformanceEvent]) -> HashMap<String, EventStats> {
        let mut stats: HashMap<String, EventStats> = HashMap::new();

        for event in events {
            if let Some(duration) = event.duration {
                let stat = stats.entry(event.name.clone()).or_insert(EventStats {
                    count: 0,
                    total_duration: 0,
                    avg_duration: 0.0,
                    min_duration: u64::MAX,
                    max_duration: 0,
                });

                stat.count += 1;
                stat.total_duration += duration;
                stat.min_duration = stat.min_duration.min(duration);
                stat.max_duration = stat.max_duration.max(duration);
                stat.avg_duration = stat.total_duration as f64 / stat.count as f64;
            }
        }

        stats
    }

    /// 清理历史数据
    pub fn cleanup(&self) {
        self.metrics_history.lock().unwrap().clear();
        self.completed_events.lock().unwrap().clear();
        self.active_events.lock().unwrap().clear();
        self.custom_metrics.lock().unwrap().clear();
    }
}

/// 性能报告
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceReport {
    pub timestamp: u64,
    pub uptime: u64,
    pub avg_cpu_usage: f32,
    pub avg_memory_usage: u64,
    pub total_events: usize,
    pub active_events_count: usize,
    pub event_stats: HashMap<String, EventStats>,
    pub recent_metrics: Vec<PerformanceMetrics>,
    pub recent_events: Vec<PerformanceEvent>,
}

/// 事件统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventStats {
    pub count: usize,
    pub total_duration: u64,
    pub avg_duration: f64,
    pub min_duration: u64,
    pub max_duration: u64,
}

/// 全局性能监控器实例
static mut PERFORMANCE_MONITOR: Option<Arc<PerformanceMonitor>> = None;
static INIT: std::sync::Once = std::sync::Once::new();

/// 获取全局性能监控器
pub fn get_performance_monitor() -> Arc<PerformanceMonitor> {
    unsafe {
        INIT.call_once(|| {
            PERFORMANCE_MONITOR = Some(Arc::new(PerformanceMonitor::new()));
        });
        PERFORMANCE_MONITOR.as_ref().unwrap().clone()
    }
}

/// 便捷宏：测量代码块执行时间
#[macro_export]
macro_rules! measure_time {
    ($name:expr, $code:block) => {{
        let monitor = crate::performance::get_performance_monitor();
        monitor.measure($name, || $code)
    }};
}

/// 便捷宏：测量异步代码块执行时间
#[macro_export]
macro_rules! measure_time_async {
    ($name:expr, $code:block) => {{
        let monitor = crate::performance::get_performance_monitor();
        monitor.measure_async($name, || async move $code).await
    }};
}
